﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Lime49.UI;
using LockCrypt.Core;

namespace LockCrypt {
    /// <summary>
    /// Shows an account or group of accounts.
    /// </summary>
    public partial class AccountView : UserControl {
        /// <summary>
        /// Occurs when an item is double clicked.
        /// </summary>
        public event RoutedPropertyChangedEventHandler<INestable> RequestNavigate;

        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(INestable), typeof(AccountView), new PropertyMetadata(new Group(), new PropertyChangedCallback(SelectedItem_Changed)));
        /// <summary>
        /// Selecteds the item count when the selected item changes.
        /// </summary>
        /// <param name="d">The AccountView.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void SelectedItem_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) {
            //todo: fix this and add a border
            AccountView view = d as AccountView;
            view.SetRecordCount(e.NewValue is IGroup ? (e.NewValue as IGroup).Children.Count : -1);
        }

        /// <summary>
        /// Gets or sets the selected account or group.
        /// </summary>
        /// <value>The selected account or group.</value>
        public INestable SelectedItem {
            get { return base.GetValue(SelectedItemProperty) as INestable; }
            set { base.SetValue(SelectedItemProperty, value); }
        }

        public static readonly DependencyProperty CurrentViewProperty = DependencyProperty.Register("CurrentView", typeof(WPFConstants.AccountViews), typeof(AccountView), new PropertyMetadata(WPFConstants.AccountViews.LargeIcons));
        /// <summary>
        /// Gets or sets the current view.
        /// </summary>
        /// <value>The current view.</value>
        public WPFConstants.AccountViews CurrentView {
            get { return (WPFConstants.AccountViews)base.GetValue(CurrentViewProperty); }
            set { base.SetValue(CurrentViewProperty, value); }
        }

        /// <summary>
        /// Gets or sets the selected items.
        /// </summary>
        /// <value>The selected items.</value>
        public IEnumerable<INestable> SelectedItems {
            get {
                ListBox ctl = Lime49.WPF.Utils.FindVisualChild<ListBox>(grpItems); // the listbox inside the datatemplate
                if(ctl == null) {
                    return new INestable[0];
                } else {
                    return ctl.SelectedItems.Cast<INestable>();
                }
            }
        }

        public AccountView() {
            InitializeComponent();
        }

        /// <summary>
        /// Copies text to the clipboard.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CopyToClipboard(object sender, ExecutedRoutedEventArgs e) {
            string textToCopy = (e.Parameter ?? string.Empty).ToString();
            SecureClipboard.CopyToClipboard(textToCopy);
        }

        /// <summary>
        /// Opens a URL.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Navigation.RequestNavigateEventArgs"/> instance containing the event data.</param>
        private void OpenUrl(object sender, ExecutedRoutedEventArgs e) {
            string url = e.Parameter.ToString();
            try {
                System.Diagnostics.Process.Start(url);
            } catch(Exception ex) {
                DialogBox.ShowAlert(Window.GetWindow(this), ex.Message, I18nUtils.GetString("Errors", "Error"));
            }
        }

        /// <summary>
        /// Reveals the contents of a password field.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void ShowPassword(object sender, ExecutedRoutedEventArgs e) {
            TextBlock txt = e.OriginalSource as TextBlock;
            string fieldValue = (e.Parameter ?? string.Empty).ToString();
            if(txt != null && fieldValue != null) {
                txt.Tag = !Convert.ToBoolean(txt.Tag);
            }
        }

        /// <summary>
        /// Sets the text for the number of items label to the left of the status bar.
        /// </summary>
        /// <param name="count">The number of items. Less than zero hides the label.</param>
        private void SetRecordCount(int count) {
            lblRecordCount.Text = count == 0 ? I18nUtils.GetString("Strings", "EmptyGroup") : I18nUtils.GetString("Strings", "NumItemsFmt", count.ToString());
        }

        /// <summary>
        /// Requests navigation to a new node.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void lst_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
            ListBox ctl = Lime49.WPF.Utils.FindVisualChild<ListBox>(grpItems); // the listbox inside the datatemplate
            if(ctl != null && ctl.SelectedItem is INestable) {
                if(RequestNavigate != null) {
                    RequestNavigate(this, new RoutedPropertyChangedEventArgs<INestable>(SelectedItem, ctl.SelectedItem as INestable));
                }
            }
        }
    }
}
